package com.grgbanking.it.system.service.impl;



import java.util.ArrayList;
import java.util.List;

import org.apache.jcs.access.exception.CacheException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.grgbanking.it.common.SystemCache;
import com.grgbanking.it.common.json.JSONHelper;
import com.grgbanking.it.system.component.WXOrganizationCreator;
import com.grgbanking.it.system.dao.IDepartmentDao;
import com.grgbanking.it.system.dao.IUserDao;
import com.grgbanking.it.system.dao.IWXDepartmentDao;
import com.grgbanking.it.system.entity.Department;
import com.grgbanking.it.system.entity.User;
import com.grgbanking.it.system.entity.WXDepartment;
import com.grgbanking.it.system.service.IDepartmentService;

/**
 * 部门管理
 * 
 * DepartmentService
 * 
 * @author 潘广伟
 * @Email p_3er@qq.com
 * @Date 2014-12-15 下午2:57:07
 * 
 * @version 1.0.0
 *
 */
@Service
public class DepartmentService implements IDepartmentService {
	@Autowired
	private IDepartmentDao<Department, Integer> departmentDao;
	@Autowired
	private IUserDao<User, Integer> userDao;
	@Autowired
	private IWXDepartmentDao<WXDepartment, Integer> wxDepartmentDao;
	@Autowired
	private WXOrganizationCreator organizationCreator;
	/**
	 * 获取部门的子部门及人员
	 * getChildren
	 * 
	 * @param deptId
	 * @return
	 * @throws Exception 
	 * @exception 
	 * @since  1.0.0
	 */
	@Override
	public String getChildren(Integer deptId) throws Exception{
		List<Department> departments = this.getAllDepartments(false);
		Department department = departmentDao.findById(deptId);
		List<Department> childDepartments = this.getChildren(departments, deptId, true);
		department.setChildren(childDepartments);
		department.setUsers(userDao.findUsersByDeptId(department.getDeptId()));
		return JSONHelper.convertObject(department);
	}
	/**
	 * 获取部门树
	 * getDepartmentTree
	 * 
	 * @param parentId
	 * @param isReflesh
	 * @return 
	 * @exception 
	 * @since  1.0.0
	 */
	@Override
	public String getDepartmentTree(Integer parentId,boolean isReflesh) throws Exception {
		if(parentId == null){
			parentId = 0;
		}
		List<Department> results = new ArrayList<Department>();
		List<Department> departments = this.getAllDepartments(isReflesh);
		
		String tree = SystemCache.getDepartmentTree();
		
		if(tree == null || isReflesh){
			for(Department department : getChildren(departments, parentId, false)){
				results.add(department);
			}
			
			tree = JSONHelper.convertDepartment(results);
			SystemCache.setDepartmentTree(tree);
		}
		
		
		return tree;
	}

	/**
	 * 递归获取子部门
	 * getChildrenDepartments
	 * 
	 * @param departments
	 * @param parentId
	 * @param isUsers 是否带部门用户信息
	 * @return 
	 * @exception 
	 * @since  1.0.0
	 */
	public List<Department> getChildren(List<Department> departments,Integer parentId, boolean isUsers){
		List<Department> results = new ArrayList<Department>();
		for(Department department : departments){
			
			if(department.getDeptParent().equals(parentId)){
				List<Department> children = getChildren(departments, department.getDeptId(), isUsers);
				if (children.size()>0) {
	                department.setChildren(children);
	            }else{
	                department.setLeaf(true);
	            }
				
				if(isUsers){
					department.setUsers(userDao.findUsersByDeptId(department.getDeptId()));
				}
				
				results.add(department);
			}
		}
		
		return results;
	}
	
	/**
	 * 同步整个部门及员工到微信
	 * updateDepartmentToWX
	 * 
	 * @param deptId
	 * @throws Exception 
	 * @exception 
	 * @since  1.0.0
	 */
	@Override
	public void updateOrganizationToWX(Integer deptId) throws Exception {
		List<Department> departments = departmentDao.findAll();
		List<User> users = userDao.findAll();
		Integer wxId = wxDepartmentDao.getWXId(deptId);
		
		if(wxId == 0){
			throw new Exception("请先同步部门！");
		}
		synchDepartment(departments,users, deptId, wxId);
		if(wxId != 1){
			List<User> usersToWX = findUsersByDepartment(users, deptId);
			this.synchUser(usersToWX,  wxId);
		}
	}
	
	/**
	 * 同步部门到微信
	 * @param departments
	 * @param parentId
	 * @param wxId
	 * @throws Exception
	 */
	private void synchDepartment(List<Department> departments,List<User> users,
			int parentId,int wxId) throws Exception{
		List<Department> departmentsToWX = findDepartmentsByParent(departments, parentId);
		
		
		for(Department department : departmentsToWX){
			department.setWxParentId(wxId);
			WXDepartment wxDepartment = organizationCreator.createDepartment(department);
			//把微信id与部门id关联写入db(未完成)
			wxDepartment.setDepartmentId(department.getDeptId());
			wxDepartmentDao.save(wxDepartment);
			
			List<User> usersToWX = findUsersByDepartment(users, department.getDeptId());
			this.synchUser(usersToWX,  wxDepartment.getWxId());
			
			this.synchDepartment(departments,users,department.getDeptId(), wxDepartment.getWxId());
		}
	}
	
	/**
	 * 同步部门用户到微信
	 * @param users
	 * @param departmentWXId
	 * @throws Exception 
	 */
	private void synchUser(List<User> users,int wxDepartmentId) throws Exception{
		for(User user : users){
			organizationCreator.createUser(wxDepartmentId, user);
		}
	}
	
	/**
	 * 根据父部门ID获取子部门集合
	 * @param departments
	 * @param parentId
	 * @return
	 */
	private List<Department> findDepartmentsByParent(List<Department> departments,
			int parentId) {
		List<Department> list = new ArrayList<Department>();
		for(Department department : departments){
			if(department.getDeptParent() == parentId){
				list.add(department);
			}
		}
		
		return list;
	}
	
	/**
	 * 根据部门ID获取用户
	 * @param users
	 * @param departmentId
	 * @return
	 */
	private List<User> findUsersByDepartment(List<User> users,int departmentId){
		List<User> list = new ArrayList<User>();
		for(User user : users){
			if(user.getDeptId() == departmentId){
				list.add(user);
			}
		}
		
		return list;
	}
	/**
	 * 获取所有部门
	 * getAllDepartments
	 * 
	 * @param isReflesh 是否刷新
	 * @return
	 * @throws CacheException 
	 * @exception 
	 * @since  1.0.0
	 */
	private List<Department> getAllDepartments(boolean isReflesh) throws CacheException{
		List<Department> departments = SystemCache.getAllDepartments();
		if(departments == null || isReflesh){
			departments = departmentDao.findAll();
			SystemCache.setAllDepartment(departments);
		}
		
		return departments;
	}
}